-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support ECDSA TSS in external signer #3734
Conversation
d3abd9a
to
62304fc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not ready for review yet
41b7fd8
to
2903436
Compare
_.isFunction(params.customPaillierModulusGeneratingFunction) && | ||
_.isFunction(params.customKShareGeneratingFunction) && | ||
_.isFunction(params.customMuDeltaShareGeneratingFunction) && | ||
_.isFunction(params.customSShareGeneratingFunction) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking: Why can't we use
typeof v === 'function'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no particular reason, i came across this first so just used it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but yeah i believe it could be used as well.
@@ -2799,7 +2810,7 @@ export class Wallet implements IWallet { | |||
} | |||
|
|||
try { | |||
const signedTxRequest = await this.tssUtils!.signUsingExternalSigner( | |||
const signedTxRequest = await this.tssUtils!.signEddsaTssUsingExternalSigner( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you assert tssUtils
above? Please don't propagate non-null asserts
* @param params signing options | ||
*/ | ||
private async signTransactionTssExternalSignerECDSA( | ||
params: WalletSignTransactionOptions = {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Option params should be last.
let txRequestId = ''; | ||
if (params.txRequestId) { | ||
txRequestId = params.txRequestId; | ||
} else if (params.txPrebuild && params.txPrebuild.txRequestId) { | ||
txRequestId = params.txPrebuild.txRequestId; | ||
} else { | ||
throw new Error('TxRequestId required to sign TSS transactions with External Signer.'); | ||
} | ||
|
||
if (!params.customPaillierModulusGeneratingFunction) { | ||
throw new Error('Generator function for paillier modulus required to sign transactions with External Signer.'); | ||
} | ||
|
||
if (!params.customKShareGeneratingFunction) { | ||
throw new Error('Generator function for K share required to sign transactions with External Signer.'); | ||
} | ||
|
||
if (!params.customMuDeltaShareGeneratingFunction) { | ||
throw new Error('Generator function for MuDelta share required to sign transactions with External Signer.'); | ||
} | ||
|
||
if (!params.customSShareGeneratingFunction) { | ||
throw new Error('Generator function for S share required to sign transactions with External Signer.'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: it would nice to extract this to its own util function and have unit tests just for this.
} | ||
|
||
try { | ||
const signedTxRequest = await this.tssUtils!.signEcdsaTssUsingExternalSigner( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't propagate non-null asserts
modules/express/src/clientRoutes.ts
Outdated
switch (req.params.sharetype) { | ||
case 'commitment': | ||
return await eddsaUtils.createCommitmentShareFromTxRequest(req.body); | ||
case 'R': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please define these magic strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ex. ShareType.R
modules/express/src/clientRoutes.ts
Outdated
customGShareGeneratingFunction: createCustomGShareGenerator(req.config.externalSignerUrl, req.params.coin), | ||
}; | ||
const coin = req.bitgo.coin(req.params.coin); | ||
if (coin.getMPCAlgorithm() === 'eddsa') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above.
modules/express/src/clientRoutes.ts
Outdated
customRShareGeneratingFunction: createCustomRShareGenerator(req.config.externalSignerUrl, req.params.coin), | ||
customGShareGeneratingFunction: createCustomGShareGenerator(req.config.externalSignerUrl, req.params.coin), | ||
}; | ||
} else if (coin.getMPCAlgorithm() === 'ecdsa') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above.
@@ -102,6 +109,208 @@ describe('External signer', () => { | |||
envStub.restore(); | |||
}); | |||
|
|||
it('should read an encrypted prv from signerFileSystemPath and pass it to PaillierModulus, K, MuDelta, and S share generators', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any non-happy path tests we can add? What about invalid inputs/configs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are a lot of missing non-happy path tests for the already supported eddsa external signer as well, i created this ticket to add non-happy path tests for external signer in general cause i think it would make this PR way too big. https://bitgoinc.atlassian.net/browse/HSM-120
challenges: { | ||
enterpriseChallenge: EcdsaTypes.SerializedEcdsaChallenges; | ||
bitgoChallenge: TxRequestChallengeResponse; | ||
}; | ||
prv: string; | ||
derivationPath: string; | ||
walletPassphrase?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: for large types, don't inline them
)) as DShare; | ||
|
||
const userSShare = await ECDSAMethods.createUserSignatureShare( | ||
userOmicronAndDeltaShare.oShare, | ||
step2Return.oShare as OShare, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we casting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the case of the hot wallet flow this step2Return would hold the actual OShare which is an OShare object, in the case of external signer it would return an encryptedOShare as a string. This is explained as a comment on the type definition of step2Return.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have better types instead of casting. Casting is almost never the fix for production app code.
2903436
to
6bf034d
Compare
6bf034d
to
a3205ae
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address comments in a follow up
c70efb5
to
3674012
Compare
3674012
to
03356c1
Compare
No description provided.